home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-04 | 9.3 KB | 378 lines | [TEXT/MMCC] |
- /*================================================================================
- Finder Snapshot
-
- ©1994 Greg Anderson
- greggor@apple.com
-
- A program that records and restores the open Finder windows
-
- ================================================================================*/
- #include <GestaltEqu.h>
- #include <Palettes.h>
- #include <TextUtils.h>
-
- #include "Main.h"
- #include "SaveWindows.h"
-
- #include "EventHandler.h"
-
- #include "StringUtilities.h"
- #include "MacUtilities.h"
- #include "AppleEventUtilities.h"
-
- #ifndef Exceptions_h
- #include "Exceptions.h"
- #endif
-
- //
- // For iuSystemScript
- //
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- //
- // For sprintf, strlen
- //
- #include <stdio.h>
- #include <string.h>
-
- //
- // Prototypes for private functions:
- //
- void InitAll(void);
- pascal OSErr QuitApplicationEvent(TAEvent& ae, TAEvent& reply, long refCon);
- pascal OSErr OpenApplicationEvent(TAEvent& ae, TAEvent& reply, long refCon);
- pascal OSErr OpenDocumentEvent(TAEvent& ae, TAEvent& reply, long refCon);
-
- //
- // Globals defined in this file:
- //
- Rect gUniverseRect;
- RgnHandle gUniverseRgn = nil;
- RgnHandle gScratchRgn = nil;
- GrafPtr gWindowMgrPort = nil;
-
- SysEnvRec gThisMacintosh;
- Boolean gHasAppleEvents;
- Boolean gApplicationShouldQuit = false;
-
- #if USESROUTINEDESCRIPTORS
- static RoutineDescriptor gQuitApplicationHandlerRD = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, QuitApplicationEvent);
- static RoutineDescriptor gOpenApplicationHandlerRD = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, OpenApplicationEvent);
- static RoutineDescriptor gOpenDocumentHandlerRD = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, OpenDocumentEvent);
- #endif
-
- //----------------------------------------------------------------------------------------
- // main:
- //----------------------------------------------------------------------------------------
- void main()
- {
- RgnHandle mouseRegion;
- AppFile theFile;
- DialogPtr splash;
- short preLoadFiles;
- short message;
- short i;
- OSErr err = noErr;
-
- //
- // Initialize all of the ToolBox managers, change the cursor
- // shape to a watch and display the splash screen.
- //
- InitAll();
- ChangeCursor(watchCursor);
-
- //
- // Every high-level-event-aware application needs a
- // quit-application handler; otherwise, it won't quit
- // when the machine is shut down (for example)
- //
- // This application quits right away, but heck, we might
- // as well keep this.
- //
- #if USESROUTINEDESCRIPTORS
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, &gQuitApplicationHandlerRD, 0, false);
- #else
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, (AEEventHandlerProcPtr) &QuitApplicationEvent, 0, false);
- #endif
-
- //
- // We definitely need an open application and
- // an open document handler
- //
- #if USESROUTINEDESCRIPTORS
- AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, &gOpenApplicationHandlerRD, 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, &gOpenDocumentHandlerRD, 0, false);
- #else
- AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, (AEEventHandlerProcPtr) &OpenApplicationEvent, 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, (AEEventHandlerProcPtr) &OpenDocumentEvent, 0, false);
- #endif
-
- //
- // Set the cursor back to an arrow
- //
- InitCursor();
-
- //
- // Set up the initial mouse region
- //
- mouseRegion = NewRgn();
-
- //
- // Set up a failure handler for failures that are not
- // trapped elsewhere
- //
- Try
- {
- //
- // Live here until the 'gApplicationShouldQuit' flag
- // becomes true
- //
- while(gApplicationShouldQuit == false)
- HandleEvents(mouseRegion);
- }
- Catch(err)
- {
- //
- // We don't expect to ever get here...
- //
- }
- } // main
-
- //----------------------------------------------------------------------------------------
- // InitAll:
- //
- // Initialize various Macintosh managers
- //----------------------------------------------------------------------------------------
- void InitAll()
- {
- OSErr theErr;
- long heapSpace;
- Ptr appLimit;
- THz appBase;
- long gestaltResult;
- short callsToMoreMasters = 10;
-
- appBase = ApplicZone();
- appLimit = GetApplLimit();
- heapSpace = FreeMem();
- MaxApplZone();
- appLimit = GetApplLimit();
- heapSpace = FreeMem();
- while( callsToMoreMasters-- )
- MoreMasters();
-
- InitGraf(&qd.thePort);
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(0L);
-
- //
- // Get the SysEnvirons record
- //
- SysEnvirons( 1, &gThisMacintosh );
-
- //
- // Check to see if AppleEvents are available
- //
- theErr = Gestalt( gestaltAppleEventsAttr, &gestaltResult );
- gHasAppleEvents = ( (theErr == noErr) && ((gestaltResult & (1L << gestaltAppleEventsPresent)) != 0) );
-
- //
- // Set a global rectangle to hold the extent of QuickDraw workspace
- // (Note: QuickDraw coordinates range from +-32767, but there
- // are bugs in QuickDraw that make it inadvisable to go beyond
- // +-16000 or so.)
- //
- SetRect(&gUniverseRect,-16000,-16000,16000,16000);
- gUniverseRgn = NewRgn();
- RectRgn(gUniverseRgn, &gUniverseRect);
- gScratchRgn = NewRgn();
- GetPort(&gWindowMgrPort);
- } // InitAll
-
- //----------------------------------------------------------------------------------------
- // ExitProgram:
- //----------------------------------------------------------------------------------------
- OSErr ExitProgram(CWindowPtr window, short item)
- {
- //
- // A "real" program would try to close all of its windows
- // first (give the user a chance to cancel)
- //
- gApplicationShouldQuit = true;
-
- return noErr;
- } // ExitProgram
-
- //----------------------------------------------------------------------------------------
- // QuitApplicationEvent:
- //----------------------------------------------------------------------------------------
- pascal OSErr QuitApplicationEvent(TAEvent& ae, TAEvent& reply, long refCon)
- {
- //
- // You should never call ExitToShell from an AppleEvent handler
- //
- gApplicationShouldQuit = true;
-
- return noErr;
- } // QuitApplicationEvent
-
- //----------------------------------------------------------------------------------------
- // MakeAnotherName
- //----------------------------------------------------------------------------------------
- void MakeAnotherName(FSSpec* newDocument)
- {
- short length = newDocument->name[0];
- unsigned char* lastChar = newDocument->name + length;
- long number = 0;
-
- //
- // First extract the number off the end of the name.
- // Not _too_ international friendly, but hey...
- //
- while((*lastChar >= '0') && (*lastChar <= '9') && (length > 0))
- {
- number = (number * 10) + (*lastChar - '0');
- --length;
- --lastChar;
- }
-
- //
- // Also strip off trailing spaces
- //
- while((*lastChar == ' ') && (length > 0))
- {
- --length;
- --lastChar;
- }
-
- //
- // Add one to the number, then append it onto the end
- // with a space.
- //
- ++number;
- ++lastChar;
- ++length;
- *lastChar = ' ';
-
- //
- // It would be a grand idea to check to see if we
- // were about to overwrite the end of the string here,
- // but we don't
- //
- ++lastChar;
- newDocument->name[0] = length;
-
- Str255 numberString;
- NumToString(number, numberString);
- pstrcat(newDocument->name, numberString);
- } // MakeAnotherName
-
- //----------------------------------------------------------------------------------------
- // OpenApplicationEvent:
- //----------------------------------------------------------------------------------------
- pascal OSErr OpenApplicationEvent(TAEvent& ae, TAEvent& reply, long refCon)
- {
- FSSpec newDocument;
- OSErr err = noErr;
- short refNum = -1;
- Boolean fileOpen = false;
-
- Try
- {
- FSMakeFSSpec(0, 0, "\pUntitled Window Set 1", &newDocument);
-
- //
- // On an open application event, we take a snapshot of all
- // of the open Finder windows and record their positions
- //
- err = dupFNErr;
- while(err == dupFNErr)
- {
- err = FSpCreate(&newDocument, 'FSNP', 'FSNP', iuSystemScript);
- if(err == dupFNErr)
- {
- MakeAnotherName(&newDocument);
- }
- }
- FailErr(err);
- HCreateResFile(newDocument.vRefNum, newDocument.parID, newDocument.name);
- FailResError();
- refNum = FSpOpenResFile(&newDocument, fsRdWrPerm);
- fileOpen = true;
-
- SaveWindowsAndPositions();
-
- CloseResFile(refNum);
- FailResError();
- fileOpen = false;
- }
- Catch(err)
- {
- if(fileOpen)
- CloseResFile(refNum);
- }
-
- //
- // Once we do that, we quit
- //
- gApplicationShouldQuit = true;
-
- return noErr;
- } // OpenApplicationEvent
-
- //----------------------------------------------------------------------------------------
- // OpenDocumentEvent:
- //----------------------------------------------------------------------------------------
- pascal OSErr OpenDocumentEvent(TAEvent& ae, TAEvent& reply, long refCon)
- {
- TDescriptor documentList;
- TDescriptor oneDocument;
- OSErr err = noErr;
- FSSpec documentToOpen;
- short refNum = -1;
- Boolean fileOpen = false;
-
- Try
- {
- documentList = ae.GetDescriptor(keyDirectObject, typeAEList);
- FOREACHDESCRIPTOR(&documentList, oneDocument)
- {
- oneDocument.GetFSS(documentToOpen);
-
- refNum = FSpOpenResFile(&documentToOpen, fsRdPerm);
- fileOpen = true;
-
- //
- // If we get an open document event, we restore all of
- // the open windows and set their position again.
- //
- RestoreAllWindowInformation();
-
- CloseResFile(refNum);
- fileOpen = false;
- }
- documentList.Dispose();
- }
- Catch(err)
- {
- if(fileOpen)
- CloseResFile(refNum);
-
- oneDocument.Dispose();
- documentList.Dispose();
- }
-
- //
- // Once we do that, we quit
- //
- gApplicationShouldQuit = true;
-
- return noErr;
- } // OpenDocumentEvent
-